home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / gamtlk11.zip / source.zip / CARIBBEAN POKER / HAND.CPP < prev    next >
C/C++ Source or Header  |  1999-12-10  |  10KB  |  360 lines

  1. //
  2. // File: Hand.CPP
  3. //
  4. // Functions for processing the HAND and CARD classes
  5. //
  6. #include "CPoker.HPP"
  7.  
  8. //
  9. // HAND::HAND(CPOKER *Frame, unsigned long ButtonBase)
  10. //
  11. // Default constructor for a hand
  12. //
  13. HAND::HAND(CPOKER* Frame, unsigned long ButtonIndex) : Name(ButtonIndex+HANDSIZE, Frame, Frame)
  14. {
  15.    int   Temp=0;
  16.    frame=Frame;
  17.  
  18.    for(Temp=0;Temp<HANDSIZE;Temp++)
  19.    {
  20.       cardButton[Temp]=new IGraphicPushButton(ButtonIndex+Temp, Frame, Frame, Frame->MainDeck.cardBack());
  21.       Card[Temp]=CARD::INVALID;
  22.    }
  23.  
  24.    // Maybe get these from the bitmaps later
  25.    cardXSize=80;
  26.    cardYSize=120;
  27.  
  28.    NumCards=0;
  29.    Value=0;
  30.    markedCards=0;
  31. }
  32.  
  33. //
  34. // bool HAND::erase()
  35. //
  36. // Erases a hand.
  37. //
  38. bool HAND::erase()
  39. {
  40.    int   Temp;
  41.  
  42.    for(Temp=0;Temp<HANDSIZE;Temp++)
  43.    {
  44.       cardButton[Temp]->setGraphic(frame->MainDeck.cardBack());
  45.       Card[Temp]=CARD::INVALID;
  46.    }
  47.    NumCards=0;
  48.    Value=0;
  49.    markedCards=0;
  50.    Name.setText("");
  51.  
  52.    return true;
  53. }
  54.  
  55. //
  56. // bool HAND::resize(ISize& newSize, IPoint& newPosition)
  57. //
  58. // Resizes the hand
  59. //
  60. bool HAND::resize(ISize newSize, IPoint newPosition)
  61. {
  62.    ISize cardSize(newSize.width()/HANDSIZE, newSize.height());
  63.    IPoint   cardStart(newPosition.x(), newPosition.y());
  64.    int   Temp=0;
  65.  
  66.    // Determine if cards are limited by height or width to maintain ratio
  67.    if(HANDSIZE*cardXSize*newSize.height()*HAND_CARDHEIGHT>cardYSize*newSize.width())
  68.    {
  69.       // Width limited
  70.       cardSize.setHeight(cardYSize*newSize.width()/HANDSIZE/cardXSize/HAND_CARDHEIGHT);
  71.       cardStart.setY((newSize.height()-cardSize.height()*HAND_CARDHEIGHT)/2+cardStart.y());
  72.    } else
  73.    {
  74.       // Height limited
  75.       cardSize.setWidth(cardXSize*newSize.height()*HAND_CARDHEIGHT/cardYSize);
  76.       cardStart.setX((newSize.width()-HANDSIZE*cardSize.width())/2+cardStart.x());
  77.    }
  78.    // Move and resize cards
  79.    Name.moveTo(cardStart);
  80.    Name.sizeTo(ISize(HANDSIZE*cardSize.width(), cardSize.height()*(1-HAND_CARDHEIGHT)));
  81.    cardStart.setY(cardStart.y()+cardSize.height()*(1-HAND_CARDHEIGHT));
  82.    cardSize.setHeight(cardSize.height()*HAND_CARDHEIGHT);
  83.    for(Temp=0;Temp<HANDSIZE;Temp++)
  84.    {
  85.       cardButton[Temp]->moveTo(cardStart);
  86.       cardButton[Temp]->sizeTo(cardSize);
  87.       cardStart.setX(cardStart.x()+cardSize.width());
  88.    }
  89.    return true;
  90. }
  91.  
  92. //
  93. // char HAND::addCard(CARD ThisCard)
  94. //
  95. // Adds a card to a hand.
  96. //
  97. char HAND::addCard(CARD ThisCard)
  98. {
  99.    char  Temp;
  100.  
  101.    for(Temp=0;Temp<HANDSIZE && Card[Temp].IsValid();Temp++);
  102.  
  103.    try
  104.    {
  105.    if(Temp<HANDSIZE)
  106.    {
  107.       Card[Temp]=ThisCard;
  108.       NumCards++;
  109.       if(!ThisCard.IsValid() || (ThisCard.Value & 0x80))
  110.          NumCards=0;
  111.       cardButton[Temp]->setGraphic(frame->MainDeck.cardFace(ThisCard));
  112.       Value=0;
  113.    }
  114.    } catch(...)
  115.    {
  116.       NumCards=0;
  117.    }
  118.    return NumCards;
  119. }
  120.  
  121. //
  122. // unsigned long HAND::evaluate()
  123. //
  124. // Evaluates a hand
  125. //
  126. unsigned long HAND::evaluate()
  127. {
  128.    char Flush=false, Straight=false, Temp, Temp2;
  129.    char Suits[CARD::SPADE+1], Faces[CARD::ACE+1];
  130.    char  MaxFace=0, MaxMatch=0, MinFace=CARD::ACE, HighFace=CARD::TWO;
  131.  
  132.    // Zero out arrays
  133.    memset(Suits, 0, sizeof(Suits));
  134.    memset(Faces, 0, sizeof(Faces));
  135.  
  136.    for(Temp=0;Temp<HANDSIZE;Temp++)
  137.    {
  138.       Suits[Card[Temp].suitOf()]++;
  139.       if(++Faces[Card[Temp].faceOf()]>MaxMatch)
  140.       {
  141.          MaxMatch++;
  142.          MaxFace=Card[Temp].faceOf();
  143.       }
  144.       if(Card[Temp].faceOf()<MinFace)
  145.          MinFace=Card[Temp].faceOf();
  146.       if(Card[Temp].faceOf()>HighFace)
  147.          HighFace=Card[Temp].faceOf();
  148.    }
  149.  
  150.    // Determine presence of flush
  151.    if(Suits[Card[0].suitOf()]==HANDSIZE)
  152.       Flush=true;
  153.  
  154.    // Determine presence of straight
  155.    if(MaxMatch==1 && ((HighFace-MinFace==HANDSIZE-1)
  156.       || (Faces[CARD::TWO]+Faces[CARD::THREE]+Faces[CARD::FOUR]+Faces[CARD::FIVE]+Faces[CARD::ACE]==HANDSIZE)))
  157.       Straight=true;
  158.  
  159.    // Check for royal flush
  160.    if(Straight && Flush && MinFace==CARD::TEN)
  161.       Value=ROYAL_FLUSH<<28;
  162.    else if(Straight && Flush)
  163.    {
  164.       Value=STRAIGHT_FLUSH<<28;
  165.       if(HighFace==CARD::ACE)
  166.          Value|=CARD::FIVE<<24;
  167.       else Value|=HighFace<<24;
  168.    } else if(MaxMatch==4)
  169.    {
  170.       // Four of a kind
  171.       Value=(FOUR_OF_A_KIND<<28) | (MaxFace<<24);
  172.  
  173.       // Find odd card
  174.       for(Temp=0;Temp<HANDSIZE && Card[Temp].faceOf()==MaxFace;Temp++);
  175.       Value|=Card[Temp].faceOf()<<20;
  176.    } else if(MaxMatch==3)
  177.    {
  178.       // Full house or three of a kind
  179.       for(Temp=CARD::TWO;Temp<=CARD::ACE && (!Faces[Temp] || Faces[Temp]==3);Temp++);
  180.  
  181.       // Note: The following assumes that two full houses are ranked according to the
  182.       // face value of the triple cards.  It must be modified if this is not the case
  183.       if(Faces[Temp]==2)
  184.          Value=(FULL_HOUSE<<28) | (MaxFace<<24) | (Temp<<20);
  185.       else
  186.       {
  187.          Value=(THREE_OF_A_KIND<<28) | (MaxFace<<24) | (Temp<<16);
  188.  
  189.          // Find odd card of higher value
  190.          for(Temp++;Temp<=CARD::ACE && Faces[Temp]!=1;Temp++);
  191.  
  192.          Value|=Temp<<20;
  193.  
  194.          // Determine pair to discard
  195.          for(Temp=0;Temp<HANDSIZE;Temp++)
  196.             if(Card[Temp].faceOf()!=MaxFace)
  197.                Value|=(1<<Temp);
  198.       }
  199.    } else if(Flush)
  200.    {
  201.       // Cards are sorted with unique face order
  202.  
  203.       for(Value=FLUSH<<28, Temp2=24, Temp=CARD::TWO;Temp<=CARD::ACE;Temp++)
  204.          if(Faces[Temp])
  205.          {
  206.             Value|=Temp<<Temp2;
  207.             Temp2-=4;
  208.          }
  209.    } else if(Straight)
  210.    {
  211.       if(HighFace==CARD::ACE && MinFace==CARD::TWO)
  212.          Value=(STRAIGHT<<28) | (CARD::FIVE<<24);
  213.       else Value=(STRAIGHT<<28) | (HighFace<<24);
  214.    } else if(MaxMatch==2)
  215.    {
  216.       // Either pair or two pair
  217.       for(Temp=CARD::TWO;Temp<=CARD::ACE && (Faces[Temp]!=2 || Temp==MaxFace);Temp++);
  218.  
  219.       if(Temp<=CARD::ACE)
  220.       {
  221.          // Two pair
  222.          Value=TWO_PAIR<<28;
  223.  
  224.          if(Temp>MaxFace)
  225.             Value|=(Temp<<24) | (MaxFace<<20);
  226.          else Value|=(MaxFace<<24) | (Temp<<20);
  227.  
  228.          // Find odd card
  229.          for(Temp=0;Temp<HANDSIZE && Faces[Card[Temp].faceOf()]!=1;Temp++);
  230.  
  231.          Value|=Card[Temp].faceOf()<<16;
  232.  
  233.          // Indicate that odd card is discarded
  234.          Value|=1<<Temp;
  235.       } else
  236.       {
  237.          // Single pair
  238.          Value=(PAIR<<28) | (MaxFace<<24);
  239.  
  240.          for(Temp2=20, Temp=CARD::ACE;Temp2>12;Temp--)
  241.             if(Faces[Temp]==1)
  242.             {
  243.                Value|=Temp<<Temp2;
  244.                Temp2-=4;
  245.             }
  246.  
  247.          // Check for four card flush.  Dump odd suited card only if so
  248.          if(Suits[Card[0].suitOf()]==HANDSIZE-1 || Suits[Card[1].suitOf()]==HANDSIZE-1)
  249.          {
  250.             for(Temp=0;Temp<HANDSIZE;Temp++)
  251.                if(Suits[Card[Temp].suitOf()]!=HANDSIZE-1)
  252.                      Value|=1<<Temp;
  253.          } else
  254.          {
  255.             for(Temp=CARD::TWO;Temp<=CARD::ACE && Faces[Temp]!=1;Temp++);
  256.  
  257.             for(Temp2=0;Temp2<HANDSIZE && Card[Temp2].faceOf()!=Temp;Temp2++);
  258.  
  259.             Value|=1<<Temp2;
  260.  
  261.             for(Temp++;Temp<=CARD::ACE && Faces[Temp]!=1;Temp++);
  262.  
  263.             for(Temp2=0;Temp2<HANDSIZE && Card[Temp2].faceOf()!=Temp;Temp2++);
  264.  
  265.             Value|=1<<Temp2;
  266.          }
  267.       }
  268.    } else if(HighFace==CARD::ACE && Faces[CARD::KING]==1)
  269.    {
  270.       // Ace/king for Caribbean Stud
  271.       for(Value=ACE_KING<<28, Temp=CARD::QUEEN, Temp2=24;Temp2>12;Temp--)
  272.          if(Faces[Temp])
  273.          {
  274.             Value|=Temp<<Temp2;
  275.             Temp2-=4;
  276.          }
  277.    } else
  278.    {
  279.       for(Value=NOTHING<<28, Temp=CARD::ACE, Temp2=24;Temp2>4;Temp--)
  280.          if(Faces[Temp])
  281.          {
  282.             Value|=Temp<<Temp2;
  283.             Temp2-=4;
  284.          }
  285.    }
  286.    if((Value>>28)<PAIR)
  287.    {
  288.       // Check for four card flush
  289.       if(Suits[Card[0].suitOf()]==HANDSIZE-1 || Suits[Card[1].suitOf()]==HANDSIZE-1)
  290.       {
  291.          for(Temp=0;Temp<HANDSIZE && Suits[Card[Temp].suitOf()]==HANDSIZE-1;Temp++);
  292.          Value|=1<<Temp;
  293.       } else
  294.       {
  295.          // Check for four card straight
  296.          for(Temp=MinFace, Temp2=0;Temp<=CARD::ACE && Temp<MinFace+HANDSIZE;Temp++)
  297.             Temp2+=Faces[Temp];
  298.          if(Temp2==HANDSIZE-1)
  299.          {
  300.             for(Temp=0;Temp<HANDSIZE && Card[Temp].faceOf()!=HighFace;Temp++);
  301.             Value|=1<<Temp;
  302.          } else
  303.          {
  304.             if(HighFace<CARD::TWO+HANDSIZE-1)
  305.                Temp=CARD::TWO;
  306.             else Temp=HighFace-HANDSIZE+1;
  307.             for(Temp2=0;Temp<=HighFace;Temp++)
  308.                Temp2+=Faces[Temp];
  309.             if(Temp2==HANDSIZE-1)
  310.             {
  311.                for(Temp=0;Temp<HANDSIZE && Card[Temp].faceOf()!=MinFace;Temp++);
  312.                Value|=1<<Temp;
  313.             } else
  314.             {
  315.                for(Temp=0;Temp<HANDSIZE && Card[Temp].faceOf()>MinFace;Temp++);
  316.                Value|=1<<Temp;
  317.                for(Temp2=HighFace, Temp=0;Temp<HANDSIZE;Temp++)
  318.                   if(Card[Temp].faceOf()<Temp2 && Card[Temp].faceOf()!=MinFace)
  319.                      Temp2=Card[Temp].faceOf();
  320.                for(Temp=0;Temp<HANDSIZE && Card[Temp].faceOf()!=Temp2;Temp++);
  321.                Value|=1<<Temp;
  322.             }
  323.          }
  324.       }
  325.    }
  326.    // Update value text
  327.    try
  328.    {
  329.       Name.setText(((Value>>24) & 0xFF)+HANDNAME_INDEX);
  330.    } catch(...)
  331.    {
  332.       try
  333.       {
  334.          Name.setText(((Value>>24) & 0xF0)+HANDNAME_INDEX);
  335.       } catch(...)
  336.       {
  337.          Name.setText("");
  338.       };
  339.    };
  340.    return Value;
  341. }
  342.  
  343. //
  344. // DECK::DECK(const char LibName[])
  345. //
  346. // Constructor for DECK
  347. //
  348. DECK::DECK(const char LibName[]) : IDynamicLinkLibrary::IDynamicLinkLibrary(LibName)
  349. {
  350.    int   Temp;
  351.  
  352.    // Load bitmaps from library
  353.    for(Temp=0;Temp<DECKSIZE;Temp++)
  354.    {
  355.       Face[Temp]=loadBitmap(Temp+FACE_INDEX);
  356.    }
  357.    Back=loadBitmap(BACK_INDEX);
  358.  
  359.    shuffle();
  360. }